#ifndef _SRC_NET_TIMER_QUEUE_H_
#define _SRC_NET_TIMER_QUEUE_H_

#include <set>
#include <vector>

#include "src/base/utils.h"
#include "src/base/time_stamp.h"
#include "src/net/callback.h"
#include "src/net/channel.h"

namespace fio66::net
{
class EventLoop;
class Timer;
class TimerId;

///
/// A best efforts timer queue.
/// No guarantee that the callback will be on time.
///
class TimerQueue
{
 public:
  DISALLOW_COPY_AND_ASSIGN(TimerQueue)
  explicit TimerQueue(EventLoop* loop);
  ~TimerQueue();

  ///
  /// Schedules the callback to be run at given time,
  /// repeats if @c interval > 0.0.
  ///
  /// Must be thread safe. Usually be called from other threads.
  TimerId AddTimer(TimerCallback cb,
                   Timestamp when,
                   double interval);
  // 取消定时器
  void Cancel(TimerId timerId);

 private:

  // FIXME: use unique_ptr<Timer> instead of raw pointers.
  // This requires heterogeneous comparison lookup (N3465) from C++14
  // so that we can find an T* in a set<unique_ptr<T>>.
  typedef std::pair<Timestamp, Timer*> Entry;
  typedef std::set<Entry> TimerList;
  typedef std::pair<Timer*, int64_t> ActiveTimer; // timer的指针和sequence
  typedef std::set<ActiveTimer> ActiveTimerSet;
  // 在timer所在的loop中添加timer
  void AddTimerInLoop(Timer* timer);
  // 在timer所在的loop中取消timer
  void CancelInLoop(TimerId timerId);
  // called when timerfd alarms
  void HandleRead();
  // move out all expired timers
  std::vector<Entry> GetExpired(Timestamp now);
  // 将到期的timer重新start，如果timer不是循环的则删除
  void Reset(const std::vector<Entry>& expired, Timestamp now);
  // 插入timer
  bool Insert(Timer* timer);

  EventLoop* loop_;
  const int timer_fd_;
  Channel timer_fd_channel_;
  // Timer list sorted by expiration
  TimerList timers_;

  // for cancel()
  ActiveTimerSet active_timers_;
  bool calling_expired_timers_; /* atomic */
  ActiveTimerSet canceling_timers_;
};
  
} // namespace fio66::net


#endif // _SRC_NET_TIMER_QUEUE_H_
